package core.transfer;

import core.place.*;
import java.io.IOException;
import core.File;
import core.exceptions.SourceTargetForTreeException;

/**
 * Class Tranfer : Manage a copy of a file between to different place (local or remote)
 * @project Universalcopy
 * @author Aurele TONNERRE, Romain Monnier
 */
public class Transfer {
    
    /*
     * The place where the file is
     */
    private Place originePlace;
    
    /*
     * The place where the file will be copy
     */
    private Place destinationPlace;
    
    /*
     * Informations about the file to copy
     */
    private File theFile;
    
    /*
     * A tranfer object who knows how to copy the file
     */
    private ProtocolTransfer transferSource;
    
    /*
     * A tranfer object who knows how to copy the file
     */
    private ProtocolTransfer transferCible;
    
    
    /**
     * Constructs a tranfer for a local copy
     * @param fullUrlSource : the path of the file (in local context)
     * @param fullUrlCible  : the path where the file will be copy (in local context)
     * @throws SourceTargetForTreeException
     */
    public Transfer(String fullUrlSource, String fullUrlCible) throws SourceTargetForTreeException {
        
        this.theFile = new File(fullUrlSource);
        this.originePlace = new PlaceLocal(this.getFilePath(fullUrlSource));
        this.destinationPlace = new PlaceLocal(this.getFilePath(fullUrlCible));
    
        this.transferCible = new LocalTransfer(fullUrlSource, fullUrlCible, theFile);
        
    }
    
    
    /**
     * Not working method !
     * @param typeSource
     * @param pathSource
     * @param portSource
     * @param loginSource
     * @param passwdSource
     * @param typeCible
     * @param pathCible
     * @param portCible
     * @param loginCible
     * @param passwdCible 
     * @throws SourceTargetForTreeException
     */
    public Transfer(String typeSource, String pathSource, int portSource, String loginSource, String passwdSource,
            String typeCible, String pathCible, int portCible, String loginCible, String passwdCible) throws SourceTargetForTreeException {
        
        
        this.theFile = new File(pathSource);
        
        // Creation de la Place pour la source
        if( typeSource.equalsIgnoreCase("ftp")) {
            this.originePlace = new PlaceFTP(this.getFilePath(pathSource), portSource, loginSource, passwdSource);
        } else if (typeSource.equalsIgnoreCase("tcpip")) {
            this.originePlace = new PlaceTCPIP(this.getFilePath(pathSource), portSource, loginSource, passwdSource);
        } else {
            this.originePlace = new PlaceHTTP(this.getFilePath(pathSource), portSource, loginSource, passwdSource);
        }
        
        
        
        // Creation de la Place pour la cible
        if( typeCible.equalsIgnoreCase("ftp")) {
            this.destinationPlace = new PlaceFTP(this.getFilePath(pathCible), portCible, loginCible, passwdCible);
        } else if (typeCible.equalsIgnoreCase("tcpip")) {
            this.destinationPlace = new PlaceTCPIP(this.getFilePath(pathCible), portCible, loginCible, passwdCible);
        } else {
            this.destinationPlace = new PlaceHTTP(this.getFilePath(pathCible), portCible, loginCible, passwdCible);
        }
        
    }
    
    
    /**
     * Constructs a tranfer for a copy a local file to a remote server
     * @param fullUrlSource : path of the local file
     * @param infoCibleDistant : informations about the place where to copy the file
     * @throws SourceTargetForTreeException
     */
    public Transfer(String fullUrlSource, String[] infoCibleDistant) throws SourceTargetForTreeException {
        
        
        System.out.println("Informations reçus pour le transfert local vers distant : ");
        System.out.println("\t\tType de cible : " + infoCibleDistant[0]);
        System.out.println("\t\tChemin du fichier source : " + fullUrlSource);
        System.out.println("\t\tChemin de la cible distante : " + infoCibleDistant[1]);
        System.out.println("\t\tAdresse serveur distant : " + infoCibleDistant[2]);
        System.out.println("\t\tLogin : " + infoCibleDistant[3]);
        System.out.println("\t\tMot de passe : " + infoCibleDistant[4]);
        System.out.println("\t\tNuméro de port : " + infoCibleDistant[5]);
        
        
        
        this.theFile = new File(fullUrlSource);
        this.originePlace = new PlaceLocal(this.getFilePath(fullUrlSource));
        
        if( infoCibleDistant[0].equalsIgnoreCase("ftp")) {
            this.destinationPlace = new PlaceFTP(this.getFilePath(infoCibleDistant[1]), Integer.parseInt(infoCibleDistant[5]), infoCibleDistant[3], infoCibleDistant[4]);
        } else if (infoCibleDistant[0].equalsIgnoreCase("tcpip")) {
            this.destinationPlace = new PlaceTCPIP(this.getFilePath(infoCibleDistant[1]), Integer.parseInt(infoCibleDistant[5]), infoCibleDistant[3], infoCibleDistant[4]);
        } else {
            this.destinationPlace = new PlaceHTTP(this.getFilePath(infoCibleDistant[1]), Integer.parseInt(infoCibleDistant[5]), infoCibleDistant[3], infoCibleDistant[4]);
        }
        
        // Création du/des transferts adéquats
        // ...
        
        
        
        
    }
    
    
    /**
     * Constructs a tranfer to copy a remote file in a local directory
     * @param infoSourceDistant : informations about the place where the file is
     * @param fullUrlCible : path of the local directory where the file will be copy
     * @throws SourceTargetForTreeException
     */
    public Transfer(String[] infoSourceDistant, String fullUrlCible) throws SourceTargetForTreeException {
        
        this.theFile = new File(infoSourceDistant[1]);
        
        if( infoSourceDistant[0].equalsIgnoreCase("ftp")) {
            this.originePlace = new PlaceFTP(this.getFilePath(infoSourceDistant[1]), Integer.parseInt(infoSourceDistant[5]), infoSourceDistant[3], infoSourceDistant[4]);
        } else if (infoSourceDistant[0].equalsIgnoreCase("tcpip")) {
            this.originePlace = new PlaceTCPIP(this.getFilePath(infoSourceDistant[1]), Integer.parseInt(infoSourceDistant[5]), infoSourceDistant[3], infoSourceDistant[4]);
        } else {
            this.originePlace = new PlaceHTTP(this.getFilePath(infoSourceDistant[1]));
            this.transferSource = new HTTPTransfer(infoSourceDistant[1], fullUrlCible, theFile);
        }
        
        this.destinationPlace = new PlaceLocal(this.getFilePath(fullUrlCible));
        
        
    }
    
    
    /**
     * Constructs a tranfer to copy a remote file to a remote server
     * @param infoSourceDistant : informations about the place where the file is
     * @param infoCibleDistant : informations about the place where to copy the file
     * @throws SourceTargetForTreeException
     */
    public Transfer(String[] infoSourceDistant, String[] infoCibleDistant) throws SourceTargetForTreeException {
        
    }
    
    
    
    
    /**
     * Returns the path of the file without the file's name
     * @param fullPath : the fullpath of the file
     * @return path : the path of the file without the file's name
     * @throws SourceTargetForTreeException
     */
    private String getFilePath(String fullPath) throws SourceTargetForTreeException {
        String path = "";
        try {
            path = fullPath.substring(0, fullPath.lastIndexOf( java.io.File.separator ) );
        } catch (StringIndexOutOfBoundsException e) {
            throw new SourceTargetForTreeException();
        }
        
        return path;
    }
    
    
    
    
    
    /**
     * Exectutes the copy
     */
    public void runTransfer()
    {
        
        try {
            
            if(this.transferCible != null && this.transferCible.getClass().getName().compareTo("core.transfer.LocalTransfer") == 0) {
                
                this.transferCible.upload();
            
            } else if(this.transferSource.getClass().getName().compareTo("core.transfer.HTTPTransfer") == 0) {
            
                this.transferSource.download();
            
            
            }
            else {
            
                //this.transferSource.download();
                //this.transferCible.upload();
                
            }
            
        }
        
        catch (IOException e) { e.printStackTrace(); } 
        catch (Exception ex) { ex.printStackTrace(); }
        
    }
    
}
